package com.code.wflow.utils;

import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ggh
 * @date 2022/9/7
 */
public class BeanCopierUtils {
    /**
     * BeanCopier的缓存
     */
    private static final ConcurrentHashMap<String, BeanCopier> BEAN_COPIER_CACHE = new ConcurrentHashMap<>();

    /**
     * BeanCopier的copy
     *
     * @param source 源对象
     * @param target 目标对象
     */
    public static void copy(Object source, Object target) {
        copy(source, target, null);
    }

    /**
     * BeanCopier的copy
     *
     * @param source    源对象
     * @param target    目标对象
     * @param converter 转换器
     */
    public static void copy(Object source, Object target, Converter converter) {
        String key = genKey(source.getClass(), target.getClass());
        BeanCopier beanCopier;
        if (BEAN_COPIER_CACHE.containsKey(key)) {
            beanCopier = BEAN_COPIER_CACHE.get(key);
        } else {
            beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
            BEAN_COPIER_CACHE.put(key, beanCopier);
        }
        beanCopier.copy(source, target, converter);
    }

    /**
     * BeanCopier的copy
     *
     * @param str 源对象
     * @param cls 目标对象类型
     * @return
     */
    public static <T> T copy(Object str, Class<T> cls) {
        return copy(str, cls, null);
    }

    public static <T> T copy(Object str, Class<T> cls, Converter converter) {
        if (str == null) {
            return null;
        }

        T dest = null;
        try {
            dest = cls.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        copy(str, dest, converter);
        return dest;
    }

    public static <S, T> List<T> copyList(List<S> srcList, Class<T> cls) {
        return copyList(srcList, cls, null);
    }

    public static <S, T> List<T> copyList(List<S> srcList, Class<T> cls, Converter converter) {
        if (CollectionUtils.isEmpty(srcList)) {
            return null;
        }
        List<T> targetList = new ArrayList<>(srcList.size());
        for (S src : srcList) {
            T target = copy(src, cls, converter);
            targetList.add(target);
        }
        return targetList;
    }

    /**
     * 生成key
     *
     * @param srcClazz 源文件的class
     * @param tgtClazz 目标文件的class
     * @return string
     */
    private static String genKey(Class<?> srcClazz, Class<?> tgtClazz) {
        return srcClazz.getName() + "_" + tgtClazz.getName();
    }
}
